/*
 *      Copyright (c) 2007 Marcelo S. Araujo
 *      All rights reserved.
 *
 *      Redistribution and use in source and binary forms, with or without
 *      modification, are permitted provided that the following conditions
 *      are met:
 *      1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *      2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 *      THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 *      ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *      IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *      ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 *      FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *      DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 *      OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *      HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *      LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *      OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *      SUCH DAMAGE.
 *
 */


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <sys/stat.h>
#include <stdio.h> // Get PWD - use this in lp function.
#include "openfile.hpp"
#include "cvscommands.hpp"
#include "pr.hpp"

using namespace std;

void Menu(int option);

int main(int argc, char *argv[])
{
	if(argv[1] == NULL) {
		Menu(0);
	} else if(!strcmp(argv[1], "help") && argv[2] == NULL) {
		Menu(1);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "co")) {
		Menu(2);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "up")) {
		Menu(3);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "diff")) {
		Menu(4);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "lp")) {
		Menu(5);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "ci")) {
		Menu(6);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "ch")) {
		Menu(7);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "getpr")) {
		Menu(8);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "takepr")) {
		Menu(9);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "closepr")) {
		Menu(10);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "addport")) {
		Menu(11);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "rmport")) {
		Menu(12);
	} else if(!strcmp(argv[1], "help") && !strcmp(argv[2], "repocopy")) {
		Menu(13);
	} else if(!strcmp(argv[1], "co") && argv[2] != NULL) {
		Cvs_CheckOut(argv[2]);
	} else if(!strcmp(argv[1], "getpr") && argv[2] != NULL) {
		GetPR(argv[2]);
		PRFile(argv[2]);
	} else if(!strcmp(argv[1], "closepr") && argv[2] != NULL) {
		ClosePR(argv[2]);
	} else if(!strcmp(argv[1], "takepr") && argv[2] != NULL) {
		TakePR(argv[2]);
	} else if(!strcmp(argv[1], "addport")) {
		if(argv[2] != NULL && argv[3] != NULL) {
			// CONTROL = 0 : Add PORT
			int CONTROL = 0;
			Cvs_AddPort(argv[2], argv[3], CONTROL);
			cout << "==> Use: pcvs ci " << "ports/" << argv[3] << "/" << argv[2] << " " << "ports/" << argv[3] << "/Makefile" << endl;
			cout << "==> Use: cd CVSROOT ; pcvs ci *" << endl;
		} else {
			cout << "Please use: ./portmenu addport <PORTNAME> <CATEGORY>" << endl;
			}
	} else if(!strcmp(argv[1], "rmport")) {
		if(argv[2] != NULL && argv[3] != NULL) {
			Cvs_RemovePort(argv[2], argv[3]);
		} else {
			cout << "Please use: ./portmenu rmport <PORTNAME> <CATEGORY>" << endl;
		}
	} else if(!strcmp(argv[1], "repocopy") && argv[2] != NULL && argv[3] != NULL) {
		Cvs_RepoCopy(argv[2], argv[3]);
	} else if(!strcmp(argv[1], "up")) {
		if(!argv[2]) {
			argv[2] = ".";
			Cvs_Update(argv[2]);
		} else {
			Cvs_Update(argv[2]);
		}
	} else if(!strcmp(argv[1], "diff")) {
		if(!argv[2]) {
			argv[2] = ".";
			Cvs_Diff(argv[2]);
		} else {
			Cvs_Diff(argv[2]);
		}
	} else if(!strcmp(argv[1], "lp")) {
		if(!argv[2]) {
			argv[2] = getcwd(NULL, 0);
			Cvs_GetLocalPatch(argv[2]);
		} else {
			Cvs_CheckOut(argv[2]);
			Cvs_GetLocalPatch(argv[2]);
		}
	} else if(!strcmp(argv[1], "ci")) {
		if(!argv[2]) {
			argv[2] = ".";
			Cvs_Commit(argv[2]);
		} else {
			Cvs_Commit(argv[2]);
		}
	} else if(!strcmp(argv[1], "ch")) {
		if(!argv[2]) {
			argv[2] = ".";
			Cvs_Commit_Check(argv[2]);
		} else {
			Cvs_Commit_Check(argv[2]);
		}
	} else {
		Menu(1);
	}
	return 0;
}

void Menu(int option) {
	cout << "+---------------------------+" << endl;
	cout << "|   PortMenu - Port Tools   |" << endl;
	cout << "+---------------------------+" << endl;

	switch(option) {
		case 1:
			cout << endl;
			cout << "* Options: co, up, diff, lp, ci, ch, getpr, takepr, closepr, addport, rmport, repocopy." << endl;
			cout << "* Get help for options." << endl;
			cout << "- You should use: ./portmenu help <OPTION>" << endl << endl;
			cout << "Try again!" << endl << endl;
			break;
		case 2:
			cout << endl << "* Creates your private copy of the source." << endl;
			cout << endl << "Use: portmenu co <PORTNAME>" << endl << endl;
			break;
		case 3:
			cout << endl << "* Execute this command when you wish to update your copies of source files." << endl;
			cout << endl << "Use: portmenu up <PORTNAME" << endl << endl;
			break;
		case 4:
			cout << endl << "* Check the differences BETWEEN your work and repository files ." << endl;
			cout << endl << "Use: portmenu diff <PORTNAME>" << endl << endl;
			break;
		case 5:
			cout << endl << "* This option gets the diff file from HOME_SITE, applies the patch," << endl;
			cout << "  cleans up the garbage files, makes an update, runs portlint and makes a diff." << endl;
			cout << endl << "Use: portmenu lp <PORTNAME>" << endl << endl;
			break;
		case 6:
			cout << endl << "* Apply your changes, additions, and deletions from your working" << endl;
			cout << "  directory to the repository." << endl;
			cout << endl << "Use: portmenu ci <PORTNAME>" << endl << endl;
			break;
		case 7:
			cout << endl << "* Update and run portlint." << endl;
			cout << endl << "Use: portmenu ch <PORTNAME>" << endl << endl;
			break;
		case 8:
			cout << endl << "* Make and output file from PRNUMBER, which you can use to get" << endl;
			cout << "  the shar file or diff file included." << endl;
			cout << endl << "Use: portmenu getpr <PRNUMBER>" << endl << endl;
			break;
		case 9:
			cout << endl << "* Take a PR in GNATS for working on it." << endl;
			cout << endl << "Use: portmenu takepr <PRNUMBER>" << endl << endl;
			break;
		case 10:
			cout << endl << "* Close PRNUMBER in GNATS." << endl;
			cout << endl << "Use: portmenu closepr <PRNUMBER>" << endl << endl;
			break;
		case 11:
			cout << endl << "* Add new port to the ports tree." << endl;
			cout << endl << "Use: portmenu addport <PORTNAME> <CATEGORY>" << endl << endl;
			break;
		case 12:
			cout << endl << "* Remove PORTNAME to the ports tree." << endl;
			cout << endl << "Use: portmenu rmport <PORTNAME>" << endl << endl;
			break;
		case 13:
			cout << endl << "* Add NEWPORTNAME into the Makefile of CATEGORY and CVSROOT/modules." << endl;
			cout << "  Removes all entries related to OLDPORTNAME." << endl;
			cout << endl << "Use: portmenu repocopy <OLDPORTNAME/OLDCATEGORY> <NEWPORTNAME/NEWCATEGORY>" << endl << endl;
			break;
		default:
			cout << endl << "* Is a tool for simplifies the work around" << endl;
			cout << "  the ports tree updates." << endl;
			cout << "* For portmenu updates and additional information, see the portmenu" << endl;
			cout << "  home page at: http://exports.googlecode.com" << endl << endl;
			cout << "Use: portmenu help" << endl << endl;
			break;
	}
};
